
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using Swaf.DataAccess;
using Swaf.Container;
using MAPI33;

namespace Swaf.Messaging 
{
	/// <summary>
	/// Scott Matthews - 10.22.2004
	/// CQ ID: CUSP00005551 - EMail Messaging Provider
	/// Summary description for ExchangeMessagingSystem.
	/// </summary>
	public class ExchangeMessagingSystem : MessagingSystemBase
	{
		private IMAPISession m_session;

		/// <summary>
		/// Default constructor
		/// </summary>
		public ExchangeMessagingSystem() {}

		/// <summary>
		/// Memeber variable to hold the connection
		/// </summary>
		protected IMessagingConnectionInfo m_connection;
		private String m_profile = String.Empty;

		#region IMessagePublisher Members
		public override void beginTrans(IMessagingConnectionInfo info)
		{
			//TODO: Log info that transactions are being used on this messaging system which does not support it.
		}

		public override void rollback(IMessagingConnectionInfo info)
		{
			//TODO: Log info that transactions are being used on this messaging system which does not support it.
		}

		public override void commit(IMessagingConnectionInfo info)
		{
			//TODO: Log info that transactions are being used on this messaging system which does not support it.
		}
		
		/// <summary>
		/// Create the message
		/// </summary>
		protected override IMessage createMessage(string msgBody, IDictionary messageProperties)
		{
			try
			{
				// Init new message
				EmailMessage message = new EmailMessage();

				// If messageProperties were provided, set them on the new Message object.
				if (messageProperties != null)
					foreach(DictionaryEntry e in messageProperties)
						Cmn.callPropertySet(message, e.Key.ToString(), e.Value);

				// Populate the body of the message and connnection configuration
				message.Body = msgBody;
				message.HostName = m_profile;

				// Return a new EmailMsg
				return new EmailMsg(message, msgBody);
			}
			catch(Exception e)
			{
				//TAC handle exception
				throw e;
			}
		}

		/// <summary>
		/// Open the connection
		/// </summary>
		protected override void open(IMessagingConnectionInfo connection)
		{
			m_connection = connection;
			open();
		}

		private void open()
		{
			try
			{
				// Get the profile from the configuration
				//MJD1: TODO: Make sure that all XChange messaging connections use HostName not ProfileName now.
				m_profile = m_connection.HostName;//connectionProperty("ProfileName");

				// Open MAPI33.MAPI
				Error hr;
				hr = MAPI33.MAPI.Initialize(null);
				
				// Ensure that the session does not already exist
				if (m_session == null)
				{
					//If connection information is available, we need to setup the connection to the MQ server.
					if (m_profile.Length > 0)
					{
						hr = MAPI33.MAPI.LogonEx(IntPtr.Zero, m_profile, null, MAPI33.MAPI.FLAGS.Extended | MAPI33.MAPI.FLAGS.NTService | MAPI33.MAPI.FLAGS.NoMail, out m_session);
					}
					else
					{
						// Attempt to use the default profile
						hr = MAPI33.MAPI.LogonEx(IntPtr.Zero, null, null, MAPI33.MAPI.FLAGS.Extended | MAPI33.MAPI.FLAGS.NTService | MAPI33.MAPI.FLAGS.NoMail, out m_session);
					}

					if (hr != Error.Success) 
						throw new ApplicationException("Unable to open the following profile: " + m_profile);
				}
			}
			catch (Exception e)
			{
				throw e;
			}
		}

		/// <summary>
		/// Open the connection
		/// </summary>
		protected override void open(string connectionName)
		{
			try
			{
				m_connection = null;
				if (! connectionName.Equals(""))
				{
					m_connection=(IMessagingConnectionInfo) Application.currentApp.appData.get("Messaging." + connectionName);
				}
				if (m_connection == null)
				{
					throw new InvalidMessagingConnectionException(String.Format("Connection {0} was not found in the Messaging Catalog",connectionName));	
				}
				open();
			}
			catch (Exception e)
			{
				throw e;
			}
		}

		/*
		private string connectionProperty(string key)
		{
			return (string) m_connection.get(key);
		}
		*/

		/// <summary>
		/// Close the connection
		/// </summary>
		protected override void close() 
		{
			// Log off the session and uninitialize MAPI33
			if (m_session != null)
			{
				m_session.Logoff(IntPtr.Zero, 0);
				m_session.Dispose();
				m_session = null;
			}
			MAPI33.MAPI.Uninitialize();
		}

		/// <summary>
		/// Publish the message with the message object and destination
		/// </summary>
		protected override void publishMessage(IMessage objMessage, string destination)
		{
			try
			{
				// Create and send the message after setting applicable properties 
				EmailMessage message = (EmailMessage) objMessage.GetMessage();
				message.To = destination.Trim();
				
				// Send the message
				MapiHelper helper = new MapiHelper();
				helper.SendMapiMessage(message, m_session);
			}
			catch (Exception e)
			{
				throw e;
			}
		}

		/// <summary>
		/// Publish the message with the message object, destination, reply to, and UNUSED: replyQueueManager
		/// </summary>
		protected override void publishMessage(IMessage objMessage, string destination, string replyDestination, string replyQueueManager)
		{
			try
			{	
				// Create and send the message after setting applicable properties
				EmailMessage message = (EmailMessage) objMessage.GetMessage();
				message.To = destination.Trim();
				message.ReplyTo = replyDestination.Trim();
				
				// Send the message
				MapiHelper helper = new MapiHelper();
				helper.SendMapiMessage(message, m_session);
			}
			catch (Exception e)
			{
				throw e;
			}

		}

		/// <summary>
		/// Publish the reply with the message object, destination, and originalMessage
		/// </summary>		
		protected override void publishReply(IMessage objMessage, string destination, IMessage originalMessage)
		{
			try
			{
				// Create and send the message after setting applicable properties
				EmailMessage message = (EmailMessage) objMessage.GetMessage();
				message.To = message.ReplyTo;
				message.From = message.To;
				
				// Send the message
				MapiHelper helper = new MapiHelper();
				helper.SendMapiMessage(message, m_session);
			}
			catch (Exception e)
			{
				throw e;
			}
		}

		/// <summary>
		/// Get the message 
		/// </summary>	
		protected override IMessage GetMessage(string source, int timeoutInMS)
		{
			// Receive the message 
			MapiHelper helper = new MapiHelper();
			EmailMessage msg = helper.ReceiveMapiMessage(m_profile, m_session);
			
			if (msg == null)
			{
				return null;
			}
			else
			{
				// Return a new EmailMsg
				EmailMsg newMessage = new EmailMsg(msg);
				newMessage.MessageSource=m_profile;
				return newMessage;
			}
		}

		/// <summary>
		/// Get the message
		/// </summary>	
		protected override IMessage GetMessage(string source, object correlationID, int timeoutInMS)
		{
			// Receive and return the message 
			return GetMessage(source, timeoutInMS);
		}

		#endregion
	}
}
